
#ifdef __APPLE__
    #include <SDL/SDL.h>
    #include "SDL/SDL_opengl.h"
    #include "SDL/SDL_image.h"
#else
    #include <SDL/SDL.h>
    #include "GL/gl.h"
    #include "GL/glu.h"
    #include "GL/glext.h"
    #include "SDL/SDL_image.h"
#endif
#include "BM_menu_object.h"

BMMenuObject::BMMenuObject(){
    // init object handler
}

void BMMenuObject::freeObject()
{
   // anitex.free();
}

/* Will modify the image array so it is vertically
flipped.
 * This is intened to be a helper function to comply
with
 * OpenGL's y-coordinate system.
 * Returns -1 on failure, 0 on success
 * Warning: The original data will be modified.
 * Sample Usage: invert_image(image->pitch, image->h,
&image->pixels)
  */

// by http://lists.libsdl.org/pipermail/sdl-libsdl.org/2002-September/030534.html
static int invert_image(int pitch, int height, void* image_pixels)
{
	int index;
	void* temp_row;
	int height_div_2;

	temp_row = (void *)malloc(pitch);
	if(NULL == temp_row)
	{
		SDL_SetError("Not enough memory for image inversion");
		return -1;
	}
	/* if height is odd, don't need to swap middle row */
	height_div_2 = (int) (height * .5);
	for(index = 0; index < height_div_2; index++) 	{
		/* uses string.h */
		memcpy((Uint8 *)temp_row,
			(Uint8 *)(image_pixels) +
			pitch * index,
			pitch);

		memcpy(
			(Uint8 *)(image_pixels) +
			pitch * index,
			(Uint8 *)(image_pixels) +
			pitch * (height - index-1),
			pitch);
		memcpy(
			(Uint8 *)(image_pixels) +
			pitch * (height - index-1),
			temp_row,
			pitch);
	}
	free(temp_row);
	return 0;
}

/* Convenience wrapper for invert_image */
int SDL_InvertSurface(SDL_Surface* image)
{
	if(NULL == image)
	{
		SDL_SetError("Surface is NULL");
		return -1;
	}
	return( invert_image(image->pitch, image->h,
			image->pixels) );
}


//int loadTexture( int n, char foldername[128]){
	/*GLuint tex;

	SDL_Surface *TextureImage[1];

    // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

    if ( ( TextureImage[0] = SDL_LoadBMP( filename ) ) ){

        SDL_InvertSurface(TextureImage[0]);

		//glGenTextures( 1, &tex);
	    glBindTexture( GL_TEXTURE_2D, tex );
	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
			     GL_LINEAR );
	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
			     GL_LINEAR );
	    glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w, TextureImage[0]->h, 0, GL_BGR, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
    }else{
		printf("Failed to load %s",filename);
		return 0;
	}
	if(tex)
        printf("Successful load %s",filename);
    // Free up any memory we may have used
    if ( TextureImage[0] )
	    SDL_FreeSurface( TextureImage[0] );

    printf("\nTexture freed");
	return tex;
	*/
//	if(!anitex.load(n,foldername))
//		return 0;
//	return 1;
///}


void BMMenuObject::createObject(int n, std::string path)
{
    // allocate space for texture
    /*image = (Image *) malloc(sizeof(Image));
    if (image == NULL) {
        printf("Error allocating space for image");
        exit(0);
    }

    if (!ImageLoad((char *)path, image)) {
        exit(1);
    }

    // Create Texture
    glGenTextures(1, &object->texture[0]);
    glBindTexture(GL_TEXTURE_2D, object->texture[0]);   // 2d texture (x and y size)

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    // 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
    // border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
    glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);

    free(image);*/

    //object->texture[0] = loadTexture((char *)path);
	anitex.load(n,path);

    yrot = 0;
    zrot = 0;
	xrot = 1.0f;
    angle = 1.0f;
}

/******************************************************************/

// quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.
// See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
// if mesa ever gets glaux, let me know.
/*
int BMMenuObject::ImageLoad(char *filename, Image *image) {
    FILE *file;
    unsigned long size;                 // size of the image in bytes.
    unsigned long i;                    // standard counter.
    unsigned short int planes;          // number of planes in image (must be 1)
    unsigned short int bpp;             // number of bits per pixel (must be 24)
    char temp;                          // used to convert bgr to rgb color.

    // make sure the file is there.
    if ((file = fopen(filename, "rb"))==NULL)
    {
        printf("File Not Found : %s\n",filename);
        return 0;
    }

    // seek through the bmp header, up to the width/height:
    fseek(file, 18, SEEK_CUR);

    // read the width
    if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
        printf("Error reading width from %s.\n", filename);
        return 0;
    }
    printf("Width of %s: %lu\n", filename, image->sizeX);

    // read the height
    if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
        printf("Error reading height from %s.\n", filename);
        return 0;
    }
    printf("Height of %s: %lu\n", filename, image->sizeY);

    // calculate the size (assuming 24 bits or 3 bytes per pixel).
    size = image->sizeX * image->sizeY * 3;

    // read the planes
    if ((fread(&planes, 2, 1, file)) != 1) {
        printf("Error reading planes from %s.\n", filename);
        return 0;
    }
    if (planes != 1) {
        printf("Planes from %s is not 1: %u\n", filename, planes);
        return 0;
    }

    // read the bpp
    if ((i = fread(&bpp, 2, 1, file)) != 1) {
        printf("Error reading bpp from %s.\n", filename);
        return 0;
    }
    if (bpp != 24) {
        printf("Bpp from %s is not 24: %u\n", filename, bpp);
        return 0;
    }

    // seek past the rest of the bitmap header.
    fseek(file, 24, SEEK_CUR);

    // read the data.
    image->data = (char *) malloc(size);
    if (image->data == NULL) {
        printf("Error allocating memory for color-corrected image data");
        return 0;
    }

    if ((i = fread(image->data, size, 1, file)) != 1) {
        printf("Error reading image data from %s.\n", filename);
        return 0;
    }

    for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
        temp = image->data[i];
        image->data[i] = image->data[i+2];
        image->data[i+2] = temp;
    }

    // we're done.
    return 1;
}
*/
/*******************************************************/
/* Draws an object to the screen
 * @param int if the object is selected/highlighted
 */
void BMMenuObject::drawObject(int is_selected, float x,float y, float z)
{
    glLoadIdentity(); // Reset The View

    glTranslatef(x,y,z);


	if(is_selected)
		anitex.updateTex();
	else{
		anitex.setCurTex(0);
		angle = 0.0f;
	}
    //if (is_selected)
    glRotatef(angle,xrot,yrot,zrot);
    //glRotatef(object->angle,object->xrot,object->yrot,object->zrot);

    glBindTexture(GL_TEXTURE_2D, anitex.getTex(anitex.getCurTex())); // choose the texture to use.


    glBegin(GL_QUADS); // begin drawing a cube
	    // Front Face (note that the texture's corners have to match the quad's corners)
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Top Left Of The Texture and Quad

    // Back Face
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Bottom Left Of The Texture and Quad


    // Back Face - inverting/flipping fixed
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Bottom Right Of The Texture and Quad

    // Top Face
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad

    // Bottom Face
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Right Of The Texture and Quad


    // Bottom Face - inverting/flipping fixed
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Right Of The Texture and Quad


    // Right face
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Left Of The Texture and Quad

    // Left Face
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f, -1.0f*0.5f);	// Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f*0.5f,  1.0f*0.5f);	// Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f*0.5f,  1.0f*0.5f);	// Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f*0.5f, -1.0f*0.5f);	// Top Left Of The Texture and Quad

    glEnd(); // done with the polygon.
}
